package com.sjy.type;


import lombok.Getter;

/**
 * @program: SDS
 * @description:
 * @author: 智慧的苏苏
 * @create: 2025-09-01 14:23
 **/

@Getter
public class SDS {
    private int len;      // 已使用的长度
    private int alloc;    // 已分配的总容量
    private byte flags;   // 存储类型
    private byte[] buf;   // 存放数据（二进制安全，和 C 一致）


    private static final byte SDS_HDR_5 = 0;
    private static final byte SDS_HDR_8 = 1;
    private static final byte SDS_HDR_16 = 2;
    private static final byte SDS_HDR_32 = 3;
    private static final byte SDS_HDR_64 = 4;

    private static final int SDS_MAX_PREALLOC = 1024 * 1024 * 1024;

    // 初始化
    public SDS(String init) {
        byte[] data = init.getBytes();
        this.len = data.length;
        this.flags = pickHDR(len);
        this.alloc = distributeSize(len) ; // 预分配策略
        this.buf = new byte[alloc];
        System.arraycopy(data, 0, buf, 0, len);
    }

    private byte pickHDR(long len) {
        if (len < 32) {
            return SDS_HDR_5;
        } else if (len < 0xff) {
            return SDS_HDR_8;
        } else if (len < 0xffff) {
            return SDS_HDR_16;
        } else if (len < 4294967295L) {
            return SDS_HDR_32;
        } else {
            return SDS_HDR_64;
        }
    }

    private int distributeSize(int len) {
        return len <= SDS_MAX_PREALLOC ? len * 2 : len + SDS_MAX_PREALLOC;
    }
    // 确保容量足够
    private void ensureCapacity(int required) {
        if (required > alloc) {
            int newAlloc = distributeSize(required);
            byte[] newBuf = new byte[newAlloc];
            System.arraycopy(buf, 0, newBuf, 0, len);
            buf = newBuf;
            alloc = newAlloc;
        }
    }


    // 转成字符串
    @Override
    public String toString() {
        return new String(buf, 0, len);
    }

    // 追加数据
    public void append(String s) {
        byte[] data = s.getBytes();
        int newLen = len + data.length;
        ensureCapacity(newLen);
        System.arraycopy(data, 0, buf, len, data.length);
        len = newLen;
        this.flags = pickHDR(len);
    }

    // 截取子串（类似 sdsrange）
    public SDS substring(int start, int end) {
        if (start < 0) start = 0;
        if (end > len) end = len;
        if (start > end) start = end;
        int subLen = end - start;
        byte[] newBuf = new byte[subLen];
        System.arraycopy(buf, start, newBuf, 0, subLen);
        SDS sds = new SDS("");
        sds.len = subLen;
        sds.alloc = subLen;
        sds.buf = newBuf;
        return sds;
    }

    // 获取当前字符串
    public String getString() {
        return new String(buf, 0, len);
    }


    public void clear() {
        len = 0;
        this.flags = pickHDR(len);
    }

    // 释放（在Java里没必要，但我们模拟）
    public void free() {
        buf = null;
        len = 0;
        alloc = 0;
        flags = 0;
    }

}
